package com.ac.util;

import java.util.ArrayList;
import java.util.List;

import javax.annotation.PostConstruct;

import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Component;

import com.ac.model.TreeModelBase;

import lombok.AllArgsConstructor;

@Component
@AllArgsConstructor
public class TreeUtil {
	/**
	 * 所有树节点顶级父级id
	 */
	public static String rootId = "0";

	static TreeUtil manger;

	final MongoTemplate mongo;

	@PostConstruct
	public void init() {
		manger = this;
	}

	/**
	 * 更新树结构中的父节点长id连接地址
	 * 
	 * @param <T>
	 * @param base
	 * @param mongo
	 * @param entityClass
	 */
	public static <T> String setRootPath(TreeModelBase base, Class<T> entityClass) {
		return setRootPath(base, entityClass, false);
	}

	/**
	 * 更新树结构中的父节点长id连接地址
	 * 
	 * @param <T>
	 * @param base
	 * @param mongo
	 * @param entityClass
	 * @param isupdate    是否直接更新数据库
	 */
	public static <T> String setRootPath(TreeModelBase base, Class<T> entityClass, boolean isupdate) {
		String parentId = base.getParentId();
		String parentPath = base.getParentPath();
		if (!parentId.equals(TreeUtil.rootId)) {
			Query query = Query.query(Criteria.where("_id").is(parentId));
			TreeModelBase parent = (TreeModelBase) manger.mongo.findOne(query, entityClass);
			if (parent != null) {
				String ppath = parent.getParentPath();
				// 兼容之前的数据进行更新处理
				if (ppath == null) {
					ppath = setRootPath(parent, entityClass, true);
				}
				parentPath = parent.getParentPath() + "#" + parent.getId();
				if (parentPath.startsWith("#")) {
					parentPath = parentPath.substring(1);
				}
			}
		}
		if (parentPath == null)
			parentPath = parentId;
		base.setParentPath(parentPath);
		if (isupdate) {
			Query query = Query.query(Criteria.where("_id").is(base.getId()));
			Update update = new Update();
			update.set("parentPath", parentPath);
			manger.mongo.updateFirst(query, update, entityClass);
		}
		return parentPath;
	}

	/**
	 * 移除节点和所有子节点并返回移除的节点id列表
	 * 
	 * @param <T>
	 * @param base
	 * @param entityClass
	 * @param mongo
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public static <T> List<String> removeId(TreeModelBase base, Class<T> entityClass) {
		List<TreeModelBase> findAllAndRemove = (List<TreeModelBase>) removeAll(base, entityClass);
		List<String> resList = new ArrayList<String>();
		for (TreeModelBase t : findAllAndRemove) {
			resList.add(t.getId());
		}
		return resList;
	}

	/**
	 * 移除所有子节点并返回移除的节点列表
	 * 
	 * @param <T>
	 * @param base
	 * @param entityClass
	 * @param mongo
	 * @return
	 */
	public static <T> List<T> removeAll(TreeModelBase base, Class<T> entityClass) {
		manger.mongo.remove(base);
		Query query = Query.query(Criteria.where("parentPath").regex(base.getId()));
		return manger.mongo.findAllAndRemove(query, entityClass);
	}
}
